local skynet = require "skynet"
local base = require "base"
local filelog = require "filelog"
local timetool = require "timetool"
local tabletool = require "tabletool"
local msghelper = require "tablehelper"
require "ddzenum"
local ddzgamelogic = require "ddzgamelogic"
local timerfunc = {}
local RETAIN = 10*60

local Table = {
	table_data = {
		idx = 0,
		seats = {},--座位信息
		waits = {}, --旁观队列 
		state = 0,
		sitdown_player_num = 0, --坐下的玩家数
		conf = nil,
		gamelogic = nil,
		timer_id = -1,
		cur_watch_playernum = 0,
		--添加桌子的变量
		delete_table_timer_id = -1,
		retain_to_time = 0,    --桌子保留到的时间(linux时间擢)
		action_seat_index = 0, --当前操作玩家的座位号
		action_to_time = 0,    --当前操作玩家的到期时间
		action_type = 0,       --玩家当前操作类型
		initCards = nil,	   --牌池
		basetimes = 1,		   --
		bomb = {},			 	---炸弹
		CardsHeaps = nil, 		---保存玩家出过的牌的牌堆
		noputsCardsNum = 0,		---一个出牌回合里,没有出牌的玩家数,不出+1，出牌则置0
		tablerecords = nil,		----记录战绩
		cur_games_times = 0,	----朋友桌记录游戏局数
		the_round = 1, 			--是否是首轮
		gamerecords = {},		--牌桌记录
		passcount = 0,			--流局次数
	},

	logic = {	-- 统一管理各种logic，以免模块各自require导致循环溢出。
		tablelogic = require "tablelogic",
		seatlogic = require "seatlogic",
		gamelogic = require "gamelogic",
		ddzlogic = ddzgamelogic:new()
	},
	retain_to_time = timetool.get_time() + RETAIN,
}

local function do_timer_func(cmd, timer_id, args)
	if type(timerfunc[cmd]) == 'function' then
		timerfunc[cmd](timer_id, args)
	else
		error("Unknown timer function: " .. cmd)
	end
end

local function add_events(name)
	local events = require(name)
	for fn, f in pairs(events) do
		if Table[fn] then
			error("duplicate function: " .. tostring(fn))
		end
		if type(f) == 'function' then
			if fn == "init" then
				f(Table)
			else
				Table[fn] = f
			end
		end
	end
end

-- 从nodecmd的 createtable()里面调用
function Table.start(conf)
	-- --[[
	if conf.room_type ~= ERoomType.ROOM_TYPE_FRIEND then
		skynet.fork(function()
			while true do
				if timetool.get_time() >= Table.retain_to_time then
					if Table.table_data.sitdown_player_num > 0 then
						filelog.warn("force delete table!", timetool.get_time(), Table.retain_to_time)
						Table.leaveallplayers()
					end
				end
				skynet.sleep(10*100)
			end
		end)
	end
	--]]
	return Table.logic.tablelogic.init(Table, conf)
end

function Table.delete()
	local code = Table.table_data.conf.table_code
	--删除桌子前清除桌子的状态
	Table.logic.tablelogic.clear(Table.table_data)
	msghelper:sendmsg_to_roomsvr("delete", code)
end

function Table.kill()
	Table.will_kill = true
	if Table.table_data.state == ETableState.TABLE_STATE_WAIT_ALL_READY then
		Table.leaveallplayers()
	end
end

function Table.leaveallplayers()
	Table.logic.tablelogic.leaveallplayers(Table.table_data)
end

function Table.exit_service()
	filelog.warn("table is deleted completely!")
	skynet.exit()
end

-- 当玩家在牌桌中时，agent上玩家身上钻石发生改变，要通知游戏
-- value为正 是增加， 负减少
function Table.rid_change_diamond(rid, begindiamond, value, enddiamond)
	if Table.table_data.conf.room_type ~= ERoomType.ROOM_TYPE_COMMON then
		return
	end
	for _, seat in pairs(Table.table_data.seats) do
		if seat.rid == rid then
			seat.diamond = seat.diamond + value
			seat.getdiamond = seat.getdiamond + value
			seat.playerinfo.diamond = seat.diamond
			assert(seat.diamond >= 0)
			assert(seat.getdiamond >= 0)
			msghelper:sendmsg_to_alltableplayer("moneychangeN", {
				money_change_list = {
					{
						rid = rid,
						money_type = 2,
						value = seat.diamond,
					},
				}
			})
			break
		end
	end
end

-- 当玩家在牌桌中时，agent上玩家身上金币发生改变，要通知游戏
-- value为正 是增加， 负减少
function Table.rid_change_coin(rid, begindiamond, value, enddiamond)
	if Table.table_data.conf.room_type ~= ERoomType.ROOM_TYPE_COIN then
		return
	end
	for _, seat in pairs(Table.table_data.seats) do
		if seat.rid == rid then
			local bets = seat.diamond_base - seat.diamond
			if seat.diamond_base + value ~= enddiamond then
				filelog.sys_error("rid_change_coin :", rid, begindiamond, value, enddiamond, seat)
			end
			-- 为了保险，同步agent数据
			seat.diamond = enddiamond - bets
			seat.getdiamond = enddiamond
			seat.diamond_base = enddiamond
			assert(seat.diamond >= 0)
			assert(seat.getdiamond >= 0)
			msghelper:sendmsg_to_alltableplayer("moneychangeN", {
				money_change_list = {
					{
						rid = rid,
						money_type = 3,
						value = seat.coin,
					},
				}
			})
			break
		end
	end
end

function Table.table_replay(request)
	local responsemsg = {}
	local logname = request.replay_logname
	if not logname then
		responsemsg.retcode = EErrCode.ERR_INVALID_PARAMS
		responsemsg.retstr = "参数错误！"
		return responsemsg
	end
	-- local logname = "ddznode_391101_1_1515044920_1515044925_0_0_116437_165672_20180104_134845"
	local _, ts = string.match(logname, "(%a+_%d+_%d+_%d+)_(%d+)")
	local logpath = skynet.getenv("logpath") .. '/' .. "tablereplay"
	logpath = logpath .. '/' .. os.date("%Y_%m_%d", ts) .."/" .. os.date("%H", ts) .. '/' .. logname .. '.log'
	filelog.warn("logpath = ", logpath)
	local file = io.open(logpath, "rb")
	local contentall = {}
	local content = {actions = {}}
	if file then
		for line in file:lines() do
			table_insert(contentall, line)
		end
		file:close()
		for i, v in ipairs(contentall) do
			if i == 4 then
				content.conf = v
			elseif i == 7 then
				content.handcards = v
			elseif i > 7 and i < #contentall then
				table_insert(content.actions, v)
			elseif i == #contentall then
				content.balance = v
			end
		end
	end
	if tabletool.is_emptytable(content) then
		responsemsg.retcode = EErrCode.ERR_ACCESSDATA_FAILED
		responsemsg.retstr = "没有找到回放文件！"
		filelog.sys_error("table_replay:没有找到回放文件！")
		return responsemsg
	end
	responsemsg.content = content
	-- filelog.debug("replaylog:", content)
	return responsemsg
end

function init()
	timerfunc = require "tabletimer"
	add_events("tablerequest")
	msghelper:init(Table)
end

local queue = require "skynet.queue"
local cs = queue()
skynet.start(function()
	skynet.dispatch("lua", function (session, source, cmd, ...)
		Table.retain_to_time = timetool.get_time() + RETAIN
		if cmd == "timer" then
			do_timer_func(...)
		else
			local f = Table[cmd]
			if type(f) == 'function' then
				local rsp = cs(f, ...)
				skynet.retpack(rsp)
			else
				error("Unknown function request:" .. cmd)
			end
		end
	end)

	init()
end)